package com.blb.demo;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 双检锁懒汉式单例模式
 */
class LazySingleton {

    //定义私有实例设置为空
    private static volatile LazySingleton instance = null;

    //重入锁对象
    private static Lock lock = new ReentrantLock();

    //私有构造方法
    private LazySingleton(){}

    public static LazySingleton getInstance(){
        // 判断对象为空，再执行同步代码，不为空跳过上锁的代码，返回对象
        if(instance == null) {
            // 保证代码原子性执行
            //上锁
            lock.lock();
            try {
                // 判断要不要创建对象
                if (instance == null) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    instance = new LazySingleton();
                }
            }finally {
                //必须保证锁一定释放
                lock.unlock();
            }
        }
        return instance;
    }

    //返回实例的方法，方法中对实例进行判断，为空才创建
//    public static LazySingleton getInstance(){
//        // 判断对象为空，再执行同步代码，不为空跳过上锁的代码，返回对象
//        if(instance == null) {
//            // 保证代码原子性执行
//            synchronized (LazySingleton.class) {
//                // 判断要不要创建对象
//                if (instance == null) {
//                    try {
//                        Thread.sleep(100);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    instance = new LazySingleton();
//                }
//            }
//        }
//        return instance;
//    }
}

public class LazySingletonDemo{
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            //多线程中创建实例
            new Thread(() ->{
                System.out.println(LazySingleton.getInstance().hashCode());
            }).start();
        }
    }
}
